/*
 * H264PropParser.h
 *
 *  Created on: 2015-3-16
 *      Author: terry
 */

#ifndef H264PROPPARSER_H_
#define H264PROPPARSER_H_

#include "BasicType.h"
#include <string>

namespace av
{


class  H264PropParser
{
public:

    class  NaluPacket
    {
    public:
        enum NaluType
        {
            NALU_NULL = 0,
            NALU_SPS = 7,
            NALU_PPS = 8,
            NALU_SEI = 6,
            NALU_IFRAME = 5
        };

        const uint8_t*    data;
        int length;
        uint8_t type;
        int prefix;

        NaluPacket() :
            data(),
            length(),
            type(),
            prefix()
        {
        }

        ~NaluPacket()
        {

        }
    };

public:
    H264PropParser();
    ~H264PropParser();

    static const size_t START_CODE_LENGTH = 4;


    static const uint8_t* getStartCode();

    static bool startWithCode(const uint8_t* data, size_t length, size_t* prefix = NULL)
    {
        return startWithH264Code(data, length, prefix);
    }

    static size_t findStartCode(const uint8_t* data, size_t length, size_t start, size_t* prefix = NULL)
    {
        return findH264StartCode(data, length, start, prefix);
    }

    static bool startWithH264Code(const uint8_t* data, size_t length, size_t* prefix = NULL);

    static size_t findH264StartCode(const uint8_t* data, size_t length, size_t start, size_t* prefix = NULL);

    static void insertStartCode(std::string& data);


    static bool splitPropSet(const uint8_t* data, size_t length,
                std::string& sps, std::string& pps);
    static bool splitPropSet(const std::string& sprop, std::string& sps, std::string& pps);

    static bool getSprop(const uint8_t* data, size_t length, std::string& sprop);

    static int removeEscape(const uint8_t* data, size_t length, std::string& nalu);

    static int removeEscape(std::string& nalu);

    static void combineToSprop(const std::string& sps, const std::string& pps,
            int profile, int level, std::string& sprop);

    static void combineToSprop(const std::string& sps, const std::string& pps, std::string& sprop);

    static void combineToSprop(const uint8_t* sps, size_t spsLength,
            const uint8_t* pps, size_t ppsLength, std::string& sprop);

    static bool parseH264ProfileLevel(const std::string& hexStr, int& profile, int& level);

    static size_t hexToData(const std::string& hexStr, std::string& data);


    static bool extractFromSdp(const char* sprop, size_t length, std::string& sps, std::string& pps);

    static bool isKeyFrame(uint8_t nalu);


    static bool parseNalu(const uint8_t* data, size_t length, NaluPacket& pkt);

    static int parseNaluType(uint8_t data);

	static void joinToSprop(const std::string& sps, const std::string& pps, std::string& sprop);

private:
    static const uint8_t s_startCode[START_CODE_LENGTH];

};



}

#endif /* H264PROPPARSER_H_ */
